package com.yaoxun.bored.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.inject.Inject;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.yaoxun.bored.ehcache.EhcacheConfig;
import com.yaoxun.bored.shiro.credential.PasswordHashedHelper;
import com.yaoxun.bored.shiro.credential.PasswordLogicCredentialsMatcher;
import com.yaoxun.bored.shiro.realm.BaseRealm;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

@Configuration
public class ShiroConfig {
	
	private static final Logger LOG = LoggerFactory.getLogger(ShiroConfig.class);
	
	@Inject
	private EhcacheConfig ehcacheConfig;
	
	public static String ALGORITHM_NAME = "md5";
	
	public static int HASH_ITERATIONS = 1;
	
	/**
	 * 配置ShiroFilterFactoryBean
	 * @author Loren
	 * @createTime 2018年1月29日 下午2:13:32
	 * @param securityManager
	 * @return
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilter() {
		LOG.info("shiro filter 初始化...");
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager()); //注入加密管理器
		//配置过滤器
		shiroFilterFactoryBean.setLoginUrl("/login");
		shiroFilterFactoryBean.setSuccessUrl("/index");
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		filterChainDefinitionMap.put("/static/**", "anon");
		filterChainDefinitionMap.put("/vcode", "anon");
		filterChainDefinitionMap.put("/login", "anon");
		filterChainDefinitionMap.put("/testHash", "anon");
		filterChainDefinitionMap.put("/**", "authc");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}
	
	
	/**
	 * 配置密码加密bean
	 * @author Loren
	 * @createTime 2018年1月29日 上午11:54:23
	 * @return
	 */
	@Bean
	public PasswordHashedHelper passwordHashedHelper() {
		PasswordHashedHelper matcher =  new PasswordHashedHelper();
		matcher.setAlgorithmName(ALGORITHM_NAME);
		matcher.setHashIterations(HASH_ITERATIONS);
		return matcher;
	}
	
	@Bean
	public HashedCredentialsMatcher credentialsMatcher() {
		PasswordLogicCredentialsMatcher matcher = new PasswordLogicCredentialsMatcher();
		matcher.setHashAlgorithmName(ALGORITHM_NAME);
		matcher.setHashIterations(HASH_ITERATIONS);
		return matcher;
	}
	
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(baseRealm());
		securityManager.setCacheManager(ehCacheManager());
		securityManager.setSessionManager(defaultWebSessionManager());
		return securityManager;
	}
	
	/**
	 * 配置基础realm
	 * @author Loren
	 * @createTime 2018年1月29日 下午2:42:10
	 * @return
	 */
	@Bean
	public BaseRealm baseRealm() {
		BaseRealm realm = new BaseRealm();
		realm.setCredentialsMatcher(credentialsMatcher());
		return realm;
	}
	
	/**
	 * 配置默认session 管理器
	 * @author Loren
	 * @createTime 2018年2月1日 上午10:03:08
	 * @return
	 */
	@Bean
	public DefaultWebSessionManager defaultWebSessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		sessionManager.setSessionIdUrlRewritingEnabled(false);
		return sessionManager;
	}
	
	/**
	 * 配置ehcache 缓存
	 * @author Loren
	 * @createTime 2018年1月29日 下午2:41:19
	 * @return
	 */
	@Bean
	public EhCacheManager ehCacheManager() {
		EhCacheManager cacheManager = new EhCacheManager();
		cacheManager.setCacheManager(ehcacheConfig.ehCacheManagerFactoryBean().getObject());
		return cacheManager;
	}
	
	/**
	 * 配置shiro的
	 * @author Loren
	 * @createTime 2018年2月1日 上午10:29:37
	 * @return
	 */
	@Bean
	public ShiroDialect shiroDialect() {
		return new ShiroDialect();
	}
	
}
